package net.wanho.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * Author：汤小洋
 * Date：2025-02-10 14:42
 * Description：<描述>
 */
@Configuration
public class RabbitMqConfig {

    @Value("${shop.exchange}")
    private String exchange;

    @Value("${shop.queue}")
    private String queue;

    @Value("${shop.routingKey}")
    private String routingKey;

    @Bean
    public Exchange exchange(){
        return new DirectExchange(exchange);
    }

    @Bean
    public Queue queue(){
        Map<String,Object> map = new HashMap<>();
        map.put("x-message-ttl", 10000); // 消息过期时间
        map.put("x-max-length", 6); // 队列最大长度
        map.put("x-dead-letter-exchange", "exchange3.direct"); // 死信交换机
        map.put("x-dead-letter-routing-key", "hello"); // 死信路由键
        Queue q = new Queue(queue,  true, false, false, map);
        return q;
    }

    @Bean
    public Binding binding(Exchange exchange, Queue queue){
        return BindingBuilder.bind(queue).to(exchange).with(routingKey).noargs();
    }

    /**
     * 消息转换器
     */
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    /**
     * 为RabbitTemplate绑定回调函数
     */
    @Resource
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init(){
        // 设置消息确认的回调函数，即消息到达交换机时的回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if(ack){
                System.out.println("成功，消息已到达交换机。。。。。。。。。。。。。。。" + correlationData.getId());
            }else{
                System.out.println("失败，消息未到达交换机。。。。。。。。。。。。。。。" + correlationData.getId());
            }
        });

        // 设置消息回退的回调函数，即消息由交换机投递到队列失败时的回调
        rabbitTemplate.setReturnsCallback(returnMessage -> {
            System.out.println("失败，消息未到达队列。。。。。。" + returnMessage.getReplyCode() + "," + returnMessage.getReplyText()); // 响应代码和响应信息
        });
    }


}
